import 'dart:io';
import 'dart:ui' as ui;
import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';
import 'package:path_provider/path_provider.dart';

class KqSignaturePad extends StatefulWidget {
  const KqSignaturePad({
    Key? key,
    this.customPaint,
    this.backgroundColor,
  }) : super(key: key);

  /// 自定义画笔
  final Paint? customPaint;

  /// 背景色
  final Color? backgroundColor;

  @override
  State<StatefulWidget> createState() => KqSignaturePadState();
}

class KqSignaturePadState extends State<KqSignaturePad> {
  /// 新路径
  Path? newPath;

  /// 过去的路径
  final List<Path> pathList = [];

  /// 通用画笔
  late Paint _paint;

  /// 画布大小
  Size? size;

  @override
  void initState() {
    super.initState();
    _paint = widget.customPaint ?? Paint()
      ..style = PaintingStyle.stroke
      ..color = Colors.black
      ..strokeWidth = 10.r
      ..strokeCap = StrokeCap.round
      ..strokeJoin = StrokeJoin.round
      ..isAntiAlias = true;
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onPanDown: (detail) {
        setState(() {
          newPath = Path()
            ..moveTo(detail.localPosition.dx, detail.localPosition.dy);
        });
      },
      onPanUpdate: (detail) {
        setState(() {
          newPath!.lineTo(detail.localPosition.dx, detail.localPosition.dy);
        });
      },
      onPanEnd: (detail) {
        setState(() {
          pathList.add(newPath!);
          newPath = null;
        });
      },
      child: RepaintBoundary(
        child: CustomPaint(
          painter: SignaturePainter(
            mPaint: _paint,
            pathList: pathList,
            newPath: newPath,
            backgroundColor: widget.backgroundColor,
            sizeListener: (size) {
              this.size = size;
            },
          ),
        ),
      ),
    );
  }

  /// 存图片并获取图片路径
  Future<String> getPicture() async {
    PictureRecorder pictureRecord = PictureRecorder();
    Canvas canvas = Canvas(pictureRecord,
        Rect.fromPoints(const Offset(0, 0), Offset(size!.width, size!.height)));
    for (Path path in pathList) {
      canvas.drawPath(path, _paint);
    }
    if (widget.backgroundColor != null) {
      canvas.drawColor(widget.backgroundColor!, BlendMode.color);
    }
    Picture picture = pictureRecord.endRecording();
    ui.Image img =
        await picture.toImage((size!.width).toInt(), (size!.height).toInt());
    // 转换为png格式的图片数据
    var bytes = await img.toByteData(format: ui.ImageByteFormat.png);
    List<int>? png = bytes?.buffer.asUint8List();
    var filePath = "";
    if (png != null) {
      // 获取手机存储（getTemporaryDirectory临时存储路径）
      Directory applicationDir = await getTemporaryDirectory();
      // getApplicationDocumentsDirectory();
      // 判断路径是否存在
      bool isDirExist = await Directory(applicationDir.path).exists();
      if (!isDirExist) Directory(applicationDir.path).create();
      // 直接保存，返回的就是保存后的文件
      File saveFile = await File(
              "${applicationDir.path}${DateTime.now().toIso8601String()}.jpg")
          .writeAsBytes(png);
      filePath = saveFile.path;
    }
    return filePath;
  }
}

class SignaturePainter extends CustomPainter {
  SignaturePainter({
    Key? key,
    this.pathList,
    this.newPath,
    this.backgroundColor,
    this.sizeListener,
    required this.mPaint,
  });

  List<Path>? pathList;

  /// 新路径
  final Path? newPath;

  final Paint mPaint;

  /// 背景色
  final Color? backgroundColor;

  final OnSizeListener? sizeListener;

  @override
  void paint(Canvas canvas, Size size) {
    if (sizeListener != null) {
      sizeListener!(size);
    }
    canvas.clipRect(
      Rect.fromPoints(const Offset(0, 0), Offset(size.width, size.height)),
    );
    if (backgroundColor != null) {
      canvas.drawColor(backgroundColor!, BlendMode.src);
    }

    /// 历史路径
    if (pathList != null) {
      for (Path path in pathList!) {
        canvas.drawPath(path, mPaint);
      }
    }

    /// 新路径
    if (newPath != null) {
      canvas.drawPath(newPath!, mPaint);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

typedef OnSizeListener = void Function(Size size);
